﻿using System;
using System.Collections;
using System.Reflection;
using Microsoft.JScript;

namespace Jsil.Compiler
{
	class AstWrapper
	{
		protected AST _ast;
		internal AstWrapper(AST ast)
		{
			_ast=ast;
		}

		protected object GetNonpublicField(string name)
		{
			return GetNonpublicField(_ast,name);
		}

		internal static object GetNonpublicField(object obj,string name)
		{
			return obj.GetType().GetField(name,BindingFlags.NonPublic|BindingFlags.Instance).GetValue(obj);
		}

		internal Context Context
		{
			get { return GetContext(_ast); }
		}

		internal static Context GetContext(AST ast)
		{
			return (Context)GetNonpublicField(ast,"context");
		}

		internal static bool IsType(AST node,string type)
		{
			Type nodeType=node.GetType();
			Type astType=typeof(AST);
			while (nodeType!=astType)
				if (nodeType.FullName==type)
					return true;
				else
					nodeType=nodeType.BaseType;

			return false;
		}
	}

	class UnaryOpWrapper:AstWrapper
	{
		internal UnaryOpWrapper(AST orig)
			: base(orig)
		{ }

		internal AST Operand { get { return (AST)GetNonpublicField("operand"); } }

		internal static bool CheckType(AST node)
		{
			return AstWrapper.IsType(node,"Microsoft.JScript.UnaryOp");
		}
	}

	class AddressOfWrapper:UnaryOpWrapper
	{
		internal AddressOfWrapper(AST orig)
			: base(orig)
		{ }

		//another props

		internal static new bool CheckType(AST node)
		{
			return AstWrapper.IsType(node,"Microsoft.JScript.AddressOf");
		}
	}

	class DeleteWrapper:UnaryOpWrapper
	{
		internal DeleteWrapper(AST orig)
			: base(orig)
		{ }

		//another props

		internal static new bool CheckType(AST node)
		{
			return AstWrapper.IsType(node,"Microsoft.JScript.Delete");
		}
	}

	class NumericUnaryWrapper:UnaryOpWrapper
	{
		internal NumericUnaryWrapper(AST orig)
			: base(orig)
		{ }

		internal JSToken OperatorTok { get { return (JSToken)GetNonpublicField("operatorTok"); } }

		internal static new bool CheckType(AST node)
		{
			return AstWrapper.IsType(node,"Microsoft.JScript.NumericUnary");
		}
	}

	class PostOrPrefixOperatorWrapper:UnaryOpWrapper
	{
		internal PostOrPrefixOperatorWrapper(AST orig)
			: base(orig)
		{ }

		internal PostOrPrefix OperatorTok { get { return (PostOrPrefix)GetNonpublicField("operatorTok"); } }

		internal static new bool CheckType(AST node)
		{
			return AstWrapper.IsType(node,"Microsoft.JScript.PostOrPrefixOperator");
		}

		internal enum PostOrPrefix
		{
			PostfixDecrement,
			PostfixIncrement,
			PrefixDecrement,
			PrefixIncrement
		}
	}

	class TypeofWrapper:UnaryOpWrapper
	{
		internal TypeofWrapper(AST orig)
			: base(orig)
		{ }

		//another props

		internal static new bool CheckType(AST node)
		{
			return AstWrapper.IsType(node,"Microsoft.JScript.Typeof");
		}
	}

	class VoidOpWrapper:UnaryOpWrapper
	{
		internal VoidOpWrapper(AST orig)
			: base(orig)
		{ }

		//another props

		internal static new bool CheckType(AST node)
		{
			return AstWrapper.IsType(node,"Microsoft.JScript.VoidOp");
		}
	}

	class ArrayLiteralWrapper:AstWrapper
	{
		internal ArrayLiteralWrapper(AST orig)
			: base(orig)
		{ }

		internal ASTList Elements { get { return (ASTList)GetNonpublicField("elements"); } }

		internal static bool CheckType(AST node)
		{
			return AstWrapper.IsType(node,"Microsoft.JScript.ArrayLiteral");
		}
	}

	class AssemblyCustomAttributeListWrapper:AstWrapper
	{
		internal AssemblyCustomAttributeListWrapper(AST orig)
			: base(orig)
		{ }

		//another props

		internal static bool CheckType(AST node)
		{
			return AstWrapper.IsType(node,"Microsoft.JScript.AssemblyCustomAttributeList");
		}
	}

	class ASTListWrapper:AstWrapper
	{
		internal ASTListWrapper(AST orig)
			: base(orig)
		{ }

		internal int Count { get { return (int)GetNonpublicField("count"); } }
		internal AST[] List { get { return (AST[])GetNonpublicField("list"); } }

		internal static bool CheckType(AST node)
		{
			return AstWrapper.IsType(node,"Microsoft.JScript.ASTList");
		}
	}

	class BinaryOpWrapper:AstWrapper
	{
		internal BinaryOpWrapper(AST orig)
			: base(orig)
		{ }

		internal AST Operand1 { get { return (AST)GetNonpublicField("operand1"); } }
		internal AST Operand2 { get { return (AST)GetNonpublicField("operand2"); } }
		internal JSToken OperatorTok { get { return (JSToken)GetNonpublicField("operatorTok"); } }

		internal static bool CheckType(AST node)
		{
			return AstWrapper.IsType(node,"Microsoft.JScript.BinaryOp");
		}
	}

	class BitwiseBinaryWrapper:BinaryOpWrapper
	{
		internal BitwiseBinaryWrapper(AST orig)
			: base(orig)
		{ }

		//another props

		internal static new bool CheckType(AST node)
		{
			return AstWrapper.IsType(node,"Microsoft.JScript.BitwiseBinary");
		}
	}

	class BitwiseBinaryAssignWrapper:BinaryOpWrapper
	{
		internal BitwiseBinaryAssignWrapper(AST orig)
			: base(orig)
		{ }

		//another props

		internal static new bool CheckType(AST node)
		{
			return AstWrapper.IsType(node,"Microsoft.JScript.BitwiseBinaryAssign");
		}
	}

	class EqualityWrapper:BinaryOpWrapper
	{
		internal EqualityWrapper(AST orig)
			: base(orig)
		{ }

		internal static new bool CheckType(AST node)
		{
			return AstWrapper.IsType(node,"Microsoft.JScript.Equality");
		}
	}

	class InWrapper:BinaryOpWrapper
	{
		internal InWrapper(AST orig)
			: base(orig)
		{ }

		//another props

		internal static new bool CheckType(AST node)
		{
			return AstWrapper.IsType(node,"Microsoft.JScript.In");
		}
	}

	class InstanceofWrapper:BinaryOpWrapper
	{
		internal InstanceofWrapper(AST orig)
			: base(orig)
		{ }

		//another props

		internal static new bool CheckType(AST node)
		{
			return AstWrapper.IsType(node,"Microsoft.JScript.Instanceof");
		}
	}

	class Logical_andWrapper:BinaryOpWrapper
	{
		internal Logical_andWrapper(AST orig)
			: base(orig)
		{ }

		internal static new bool CheckType(AST node)
		{
			return AstWrapper.IsType(node,"Microsoft.JScript.Logical_and");
		}
	}

	class Logical_orWrapper:BinaryOpWrapper
	{
		internal Logical_orWrapper(AST orig)
			: base(orig)
		{ }

		internal static new bool CheckType(AST node)
		{
			return AstWrapper.IsType(node,"Microsoft.JScript.Logical_or");
		}
	}

	class PlusWrapper:BinaryOpWrapper
	{
		internal PlusWrapper(AST orig)
			: base(orig)
		{ }

		internal static new bool CheckType(AST node)
		{
			return AstWrapper.IsType(node,"Microsoft.JScript.Plus");
		}
	}

	class PlusAssignWrapper:BinaryOpWrapper
	{
		internal PlusAssignWrapper(AST orig)
			: base(orig)
		{ }

		internal static new bool CheckType(AST node)
		{
			return AstWrapper.IsType(node,"Microsoft.JScript.PlusAssign");
		}
	}

	class CommaWrapper:BinaryOpWrapper
	{
		internal CommaWrapper(AST orig)
			: base(orig)
		{ }

		//another props

		internal static new bool CheckType(AST node)
		{
			return AstWrapper.IsType(node,"Microsoft.JScript.Comma");
		}
	}

	class NumericBinaryWrapper:BinaryOpWrapper
	{
		internal NumericBinaryWrapper(AST orig)
			: base(orig)
		{ }

		internal static new bool CheckType(AST node)
		{
			return AstWrapper.IsType(node,"Microsoft.JScript.NumericBinary");
		}
	}

	class NumericBinaryAssignWrapper:BinaryOpWrapper
	{
		internal NumericBinaryAssignWrapper(AST orig)
			: base(orig)
		{ }

		//another props

		internal static new bool CheckType(AST node)
		{
			return AstWrapper.IsType(node,"Microsoft.JScript.NumericBinaryAssign");
		}
	}

	class RelationalWrapper:BinaryOpWrapper
	{
		internal RelationalWrapper(AST orig)
			: base(orig)
		{ }

		internal static new bool CheckType(AST node)
		{
			return AstWrapper.IsType(node,"Microsoft.JScript.Relational");
		}
	}

	class StrictEqualityWrapper:BinaryOpWrapper
	{
		internal StrictEqualityWrapper(AST orig)
			: base(orig)
		{ }

		//another props

		internal static new bool CheckType(AST node)
		{
			return AstWrapper.IsType(node,"Microsoft.JScript.StrictEquality");
		}
	}

	class BindingWrapper:AstWrapper
	{
		internal BindingWrapper(AST orig)
			: base(orig)
		{ }

		internal string Name { get { return (string)GetNonpublicField("name"); } }

		internal static string GetName(AST node)
		{
			return (string)GetNonpublicField(node,"name");
		}

		internal static bool CheckType(AST node)
		{
			return AstWrapper.IsType(node,"Microsoft.JScript.Binding");
		}
	}

	class CallableExpressionWrapper:BindingWrapper
	{
		internal CallableExpressionWrapper(AST orig)
			: base(orig)
		{ }

		internal AST Operand { get { return (AST)GetNonpublicField("operand"); } }

		internal static new bool CheckType(AST node)
		{
			return AstWrapper.IsType(node,"Microsoft.JScript.CallableExpression");
		}
	}

	class LookupWrapper:BindingWrapper
	{
		internal LookupWrapper(AST orig)
			: base(orig)
		{ }

		//another props

		internal static new bool CheckType(AST node)
		{
			return AstWrapper.IsType(node,"Microsoft.JScript.Lookup");
		}
	}

	class MemberWrapper:BindingWrapper
	{
		internal MemberWrapper(AST orig)
			: base(orig)
		{ }

		internal AST RootObject { get { return (AST)GetNonpublicField("rootObject"); } }

		internal static new bool CheckType(AST node)
		{
			return AstWrapper.IsType(node,"Microsoft.JScript.Member");
		}
	}

	class BlockWrapper:AstWrapper
	{
		internal BlockWrapper(AST orig)
			: base(orig)
		{ }

		internal ArrayList List { get { return (ArrayList)GetNonpublicField("list"); } }

		internal static bool CheckType(AST node)
		{
			return AstWrapper.IsType(node,"Microsoft.JScript.Block");
		}
	}

	class ConstantWrapperWrapper:AstWrapper
	{
		internal ConstantWrapperWrapper(AST orig)
			: base(orig)
		{ }

		internal object Value { get { return GetNonpublicField("value"); } }
		internal bool IsNumericLiteral { get { return (bool)GetNonpublicField("isNumericLiteral"); } }

		internal static bool CheckType(AST node)
		{
			return AstWrapper.IsType(node,"Microsoft.JScript.ConstantWrapper");
		}
	}

	class EmptyLiteralWrapper:ConstantWrapperWrapper
	{
		internal EmptyLiteralWrapper(AST orig)
			: base(orig)
		{ }

		//another props

		internal static new bool CheckType(AST node)
		{
			return AstWrapper.IsType(node,"Microsoft.JScript.EmptyLiteral");
		}
	}

	class NullLiteralWrapper:ConstantWrapperWrapper
	{
		internal NullLiteralWrapper(AST orig)
			: base(orig)
		{ }

		//another props

		internal static new bool CheckType(AST node)
		{
			return AstWrapper.IsType(node,"Microsoft.JScript.NullLiteral");
		}
	}

	class ConstructorCallWrapper:AstWrapper
	{
		internal ConstructorCallWrapper(AST orig)
			: base(orig)
		{ }

		//another props

		internal static bool CheckType(AST node)
		{
			return AstWrapper.IsType(node,"Microsoft.JScript.ConstructorCall");
		}
	}

	class CustomAttributeListWrapper:AstWrapper
	{
		internal CustomAttributeListWrapper(AST orig)
			: base(orig)
		{ }

		//another props

		internal static bool CheckType(AST node)
		{
			return AstWrapper.IsType(node,"Microsoft.JScript.CustomAttributeList");
		}
	}

	class DebugBreakWrapper:AstWrapper
	{
		internal DebugBreakWrapper(AST orig)
			: base(orig)
		{ }

		internal static bool CheckType(AST node)
		{
			return AstWrapper.IsType(node,"Microsoft.JScript.DebugBreak");
		}
	}

	class EvalWrapper:AstWrapper
	{
		internal EvalWrapper(AST orig)
			: base(orig)
		{ }

		//another props

		internal static bool CheckType(AST node)
		{
			return AstWrapper.IsType(node,"Microsoft.JScript.Eval");
		}
	}

	class ForInWrapper:AstWrapper
	{
		internal ForInWrapper(AST orig)
			: base(orig)
		{ }

		//another props

		internal static bool CheckType(AST node)
		{
			return AstWrapper.IsType(node,"Microsoft.JScript.ForIn");
		}
	}

	class FunctionDeclarationWrapper:AstWrapper
	{
		internal FunctionDeclarationWrapper(AST orig)
			: base(orig)
		{ }

		internal FunctionObject Func { get { return (FunctionObject)GetNonpublicField("func"); } }
		internal bool IsMethod { get { return (bool)GetNonpublicField("isMethod"); } }
		internal string Name { get { return (string)GetNonpublicField("name"); } }

		internal static bool CheckType(AST node)
		{
			return AstWrapper.IsType(node,"Microsoft.JScript.FunctionDeclaration");
		}
	}

	class FunctionObjectWrapper
	{
		FunctionObject _orig;
		internal FunctionObjectWrapper(FunctionObject orig)
		{
			_orig=orig;
		}

		internal ParameterDeclarationWrapper[] ParameterDeclarations
		{
			get
			{
				IList list=(IList)AstWrapper.GetNonpublicField(_orig,"parameter_declarations");
				ParameterDeclarationWrapper[] result=new ParameterDeclarationWrapper[list.Count];
				int a=0;
				foreach (object item in list)
					result[a++]=new ParameterDeclarationWrapper(item);
				return result;
			}
		}

		internal Block Body { get { return (Block)AstWrapper.GetNonpublicField(_orig,"body"); } }
	}

	class ParameterDeclarationWrapper
	{
		object _paramDeclar;
		internal ParameterDeclarationWrapper(object parametrDeclaration)
		{
			_paramDeclar=parametrDeclaration;
		}

		internal string Name { get { return (string)_paramDeclar.GetType().GetProperty("Name",BindingFlags.Public|BindingFlags.Instance).GetValue(_paramDeclar,new object[0]); } }

		/*internal ??? DefaultValue
		{
			get {return (???)_paramDeclar.GetType().GetProperty("DefaultValue",BindingFlags.Public|BindingFlags.Instance).GetValue(_paramDeclar,new object[0]);}
		}*/
	}

	class FunctionExpressionWrapper:AstWrapper
	{
		internal FunctionExpressionWrapper(AST orig)
			: base(orig)
		{ }

		internal FunctionObject Func { get { return (FunctionObject)GetNonpublicField("func"); } }
		internal string Name { get { return (string)GetNonpublicField("name"); } }

		internal static bool CheckType(AST node)
		{
			return AstWrapper.IsType(node,"Microsoft.JScript.FunctionExpression");
		}
	}

	class ImportWrapper:AstWrapper
	{
		internal ImportWrapper(AST orig)
			: base(orig)
		{ }

		internal string Name { get { return (string)GetNonpublicField("name"); } }
		internal static string GetName(AST ast)
		{
			return (string)AstWrapper.GetNonpublicField(ast,"name");
		}

		internal static bool CheckType(AST node)
		{
			return AstWrapper.IsType(node,"Microsoft.JScript.Import");
		}
	}

	class PackageWrapper:AstWrapper
	{
		internal PackageWrapper(AST orig)
			: base(orig)
		{ }

		//another props

		internal static bool CheckType(AST node)
		{
			return AstWrapper.IsType(node,"Microsoft.JScript.Package");
		}
	}

	class ScriptBlockWrapper:AstWrapper
	{
		internal ScriptBlockWrapper(AST orig)
			: base(orig)
		{ }

		internal Block Statement { get { return (Block)GetNonpublicField("statement_block"); } }

		internal static bool CheckType(AST node)
		{
			return AstWrapper.IsType(node,"Microsoft.JScript.ScriptBlock");
		}
	}

	class ThrowWrapper:AstWrapper
	{
		internal ThrowWrapper(AST orig)
			: base(orig)
		{ }

		internal AST Operand { get { return (AST)GetNonpublicField("operand"); } }

		internal static bool CheckType(AST node)
		{
			return AstWrapper.IsType(node,"Microsoft.JScript.Throw");
		}
	}

	class TryWrapper:AstWrapper
	{
		internal TryWrapper(AST orig)
			: base(orig)
		{ }

		//another props
		internal Block Body { get { return (Block)GetNonpublicField("body"); } }
		internal Block Handler { get { return (Block)GetNonpublicField("handler"); } }
		internal string ExceptionVariableName
		{
			get
			{
				return (string)GetNonpublicField(GetNonpublicField("field"),"debuggerName");
			}
		}

		internal static bool CheckType(AST node)
		{
			return AstWrapper.IsType(node,"Microsoft.JScript.Try");
		}
	}

	class TypeExpressionWrapper:AstWrapper
	{
		internal TypeExpressionWrapper(AST orig)
			: base(orig)
		{ }

		//another props

		internal static bool CheckType(AST node)
		{
			return AstWrapper.IsType(node,"Microsoft.JScript.TypeExpression");
		}
	}

	class WithWrapper:AstWrapper
	{
		internal WithWrapper(AST orig)
			: base(orig)
		{ }

		//another props

		internal static bool CheckType(AST node)
		{
			return AstWrapper.IsType(node,"Microsoft.JScript.With");
		}
	}

	class AssignWrapper:AstWrapper
	{
		internal AssignWrapper(AST orig)
			: base(orig)
		{ }

		internal AST Lhside { get { return (AST)GetNonpublicField("lhside"); } }
		internal AST Rhside { get { return (AST)GetNonpublicField("rhside"); } }

		internal static bool CheckType(AST node)
		{
			return AstWrapper.IsType(node,"Microsoft.JScript.Assign");
		}
	}

	class BreakWrapper:AstWrapper
	{
		internal BreakWrapper(AST orig)
			: base(orig)
		{ }

		//another props

		internal static bool CheckType(AST node)
		{
			return AstWrapper.IsType(node,"Microsoft.JScript.Break");
		}
	}

	class CallWrapper:AstWrapper
	{
		internal CallWrapper(AST orig)
			: base(orig)
		{ }

		internal ASTList Args { get { return (ASTList)GetNonpublicField("args"); } }
		internal AST Func { get { return (AST)GetNonpublicField("func"); } }
		internal bool IsArray { get { return (bool)GetNonpublicField("inBrackets"); } }
		internal bool IsConstructor { get { return (bool)GetNonpublicField("isConstructor"); } }

		internal static bool CheckType(AST node)
		{
			return AstWrapper.IsType(node,"Microsoft.JScript.Call");
		}
	}

	class ClassWrapper:AstWrapper
	{
		internal ClassWrapper(AST orig)
			: base(orig)
		{ }

		//another props

		internal static bool CheckType(AST node)
		{
			return AstWrapper.IsType(node,"Microsoft.JScript.Class");
		}
	}

	class EnumDeclarationWrapper:ClassWrapper
	{
		internal EnumDeclarationWrapper(AST orig)
			: base(orig)
		{ }

		//another props

		internal static new bool CheckType(AST node)
		{
			return AstWrapper.IsType(node,"Microsoft.JScript.EnumDeclaration");
		}
	}

	class ConditionalWrapper:AstWrapper
	{
		internal ConditionalWrapper(AST orig)
			: base(orig)
		{ }

		internal AST Condition { get { return (AST)GetNonpublicField("condition"); } }
		internal AST Operand1 { get { return (AST)GetNonpublicField("operand1"); } }
		internal AST Operand2 { get { return (AST)GetNonpublicField("operand2"); } }

		internal static bool CheckType(AST node)
		{
			return AstWrapper.IsType(node,"Microsoft.JScript.Conditional");
		}
	}

	class ConstantWrapper:AstWrapper
	{
		internal ConstantWrapper(AST orig)
			: base(orig)
		{ }

		//another props

		internal static bool CheckType(AST node)
		{
			return AstWrapper.IsType(node,"Microsoft.JScript.Constant");
		}
	}

	class ContinueWrapper:AstWrapper
	{
		internal ContinueWrapper(AST orig)
			: base(orig)
		{ }

		//another props

		internal static bool CheckType(AST node)
		{
			return AstWrapper.IsType(node,"Microsoft.JScript.Continue");
		}
	}

	class CustomAttributeWrapper:AstWrapper
	{
		internal CustomAttributeWrapper(AST orig)
			: base(orig)
		{ }

		//another props

		internal static bool CheckType(AST node)
		{
			return AstWrapper.IsType(node,"Microsoft.JScript.CustomAttribute");
		}
	}

	class DoWhileWrapper:AstWrapper
	{
		internal DoWhileWrapper(AST orig)
			: base(orig)
		{ }

		//another props

		internal static bool CheckType(AST node)
		{
			return AstWrapper.IsType(node,"Microsoft.JScript.DoWhile");
		}
	}

	class ExpressionWrapper:AstWrapper
	{
		internal ExpressionWrapper(AST orig)
			: base(orig)
		{ }

		internal AST Operand { get { return (AST)GetNonpublicField("operand"); } }

		internal static bool CheckType(AST node)
		{
			return AstWrapper.IsType(node,"Microsoft.JScript.Expression");
		}
	}

	class ForWrapper:AstWrapper
	{
		internal ForWrapper(AST orig)
			: base(orig)
		{ }

		internal AST Initializer { get { return (AST)GetNonpublicField("initializer"); } }
		internal AST Condition { get { return (AST)GetNonpublicField("condition"); } }
		internal AST Incrementer { get { return (AST)GetNonpublicField("incrementer"); } }
		internal AST Body { get { return (AST)GetNonpublicField("body"); } }

		internal static bool CheckType(AST node)
		{
			return AstWrapper.IsType(node,"Microsoft.JScript.For");
		}
	}

	class IdentifierLiteralWrapper:AstWrapper
	{
		internal IdentifierLiteralWrapper(AST orig)
			: base(orig)
		{ }

		//another props

		internal static bool CheckType(AST node)
		{
			return AstWrapper.IsType(node,"Microsoft.JScript.IdentifierLiteral");
		}
	}

	class IfWrapper:AstWrapper
	{
		internal IfWrapper(AST orig)
			: base(orig)
		{ }

		internal AST Condition { get { return (AST)GetNonpublicField("condition"); } }
		internal AST Operand1 { get { return (AST)GetNonpublicField("operand1"); } }
		internal AST Operand2 { get { return (AST)GetNonpublicField("operand2"); } }

		internal static bool CheckType(AST node)
		{
			return AstWrapper.IsType(node,"Microsoft.JScript.If");
		}
	}

	class ObjectLiteralWrapper:AstWrapper
	{
		internal ObjectLiteralWrapper(AST orig)
			: base(orig)
		{ }

		internal AST[] Keys { get { return (AST[])GetNonpublicField("keys"); } }
		internal AST[] Values { get { return (AST[])GetNonpublicField("values"); } }

		internal static bool CheckType(AST node)
		{
			return AstWrapper.IsType(node,"Microsoft.JScript.ObjectLiteral");
		}
	}

	class PrintWrapper:AstWrapper
	{
		internal PrintWrapper(AST orig)
			: base(orig)
		{ }

		//another props

		internal static bool CheckType(AST node)
		{
			return AstWrapper.IsType(node,"Microsoft.JScript.Print");
		}
	}

	class RegExpLiteralWrapper:AstWrapper
	{
		internal RegExpLiteralWrapper(AST orig)
			: base(orig)
		{ }

		internal string Source { get { return (string)GetNonpublicField("source"); } }
		internal bool IgnoreCase { get { return (bool)GetNonpublicField("ignoreCase"); } }
		internal bool Global { get { return (bool)GetNonpublicField("global"); } }
		internal bool Multiline { get { return (bool)GetNonpublicField("multiline"); } }

		internal static bool CheckType(AST node)
		{
			return AstWrapper.IsType(node,"Microsoft.JScript.RegExpLiteral");
		}
	}

	class ReturnWrapper:AstWrapper
	{
		internal ReturnWrapper(AST orig)
			: base(orig)
		{ }

		internal AST Operand { get { return (AST)GetNonpublicField("operand"); } }

		internal static bool CheckType(AST node)
		{
			return AstWrapper.IsType(node,"Microsoft.JScript.Return");
		}
	}

	class StaticInitializerWrapper:AstWrapper
	{
		internal StaticInitializerWrapper(AST orig)
			: base(orig)
		{ }

		//another props

		internal static bool CheckType(AST node)
		{
			return AstWrapper.IsType(node,"Microsoft.JScript.StaticInitializer");
		}
	}

	class SwitchWrapper:AstWrapper
	{
		internal SwitchWrapper(AST orig)
			: base(orig)
		{ }

		internal AST Expression { get { return (AST)GetNonpublicField("expression"); } }
		internal ASTList Cases { get { return (ASTList)GetNonpublicField("cases"); } }
		internal int DefaultCaseIndex { get { return (int)GetNonpublicField("default_case"); } }


		internal static bool CheckType(AST node)
		{
			return AstWrapper.IsType(node,"Microsoft.JScript.Switch");
		}
	}

	class SwitchCaseWrapper:AstWrapper
	{
		internal SwitchCaseWrapper(AST orig)
			: base(orig)
		{ }

		internal AST CaseValue { get { return (AST)GetNonpublicField("case_value"); } }
		internal AST Statements { get { return (AST)GetNonpublicField("statements"); } }

		internal static bool CheckType(AST node)
		{
			return AstWrapper.IsType(node,"Microsoft.JScript.SwitchCase");
		}
	}

	class ThisLiteralWrapper:AstWrapper
	{
		internal ThisLiteralWrapper(AST orig)
			: base(orig)
		{ }

		//another props

		internal static bool CheckType(AST node)
		{
			return AstWrapper.IsType(node,"Microsoft.JScript.ThisLiteral");
		}
	}

	class VariableDeclarationWrapper:AstWrapper
	{
		internal VariableDeclarationWrapper(AST orig)
			: base(orig)
		{ }

		internal Binding Identifier { get { return (Binding)GetNonpublicField("identifier"); } }
		internal AST Initializer { get { return (AST)GetNonpublicField("initializer"); } }

		internal static bool CheckType(AST node)
		{
			return AstWrapper.IsType(node,"Microsoft.JScript.VariableDeclaration");
		}
	}

	class WhileWrapper:AstWrapper
	{
		internal WhileWrapper(AST orig)
			: base(orig)
		{ }

		internal AST Condition { get { return (AST)GetNonpublicField("condition"); } }
		internal AST Body { get { return (AST)GetNonpublicField("body"); } }

		internal static bool CheckType(AST node)
		{
			return AstWrapper.IsType(node,"Microsoft.JScript.While");
		}
	}
}
